<?php

declare(strict_types=1);
// 库存单据-采购模块
namespace app\net2023dev\controller;

use think\facade\Db; //门面模式
use app\net2023dev\model\OrderBuyer as mysql; //导入模型
class OrderBuyer
{
    // 新增
    public function new()
    {
        $query = request()->param(); //请求参数
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);



        // 系统单号-前缀-`type` 单据类型_A1采购入库B1采购退货C赠品入库D1报损出库
        $fv = $query['table_header']['type'];
        switch ($fv) {
            case "A1":
                $dbid_num = '91'; //系统单号-前缀
                break;
            case "B1":
                $dbid_num = '81'; //系统单号-前缀
                break;
            case "C1":
                $dbid_num = '71'; //系统单号-前缀
                break;
            case "D1":
                $dbid_num = '61'; //系统单号-前缀
                break;
            default:
                $dbid_num = '11'; //系统单号-前缀
        }

        $dbid = $dbid_num . date('ymdHis', $time_int) . rand(1000, 9999); //采购订单：前缀+2位年月日时分秒+四位随机数。例： "dbid": "9231114190243"
        // 订单表头写入
        $sqldb = mysql::create(
            [
                'dbid' => $dbid, //数据编号.唯一(系统单号)
                'type' => (isset($query['table_header']['type']) && !empty($query['table_header']['type'])) ? $query['table_header']['type'] : 'A1', //单据类型_A1采购入库B1采购退货C1赠品入库D1报损出库
                'state' => 'A', //单据状态_A草稿B审核C作废
                'original_no' => (isset($query['table_header']['original_no']) && !empty($query['table_header']['original_no'])) ? $query['table_header']['original_no'] : '原始单号', //原始单号
                'remark' => (isset($query['table_header']['remark']) && !empty($query['table_header']['remark'])) ? $query['table_header']['remark'] : '单据备注', //单据备注
                'time_new' => $time_int, //创建时间
                'time_up' => $time_int, //修改时间

                'detail_length_query' => count($query["table_detail"]), //明细请求长度
                'detail_length_insert' => 0, //明细写入长度

                'db_json' => json_encode($query, JSON_UNESCAPED_UNICODE), //静态JSON
            ]
        );
        // 订单表头写入-成功
        if ($sqldb) {
            $code = 200;
            $msg = "订单表头写入-成功";
            $data_now = $sqldb->toArray();
            // 初始化数组结构
            $insert_data = [
                [
                    "order_dbid" => $data_now["dbid"], //对应订单数据编号
                    "goods_dbid" => null, //商品数据编号
                    "number" => null, //数量
                    "prc_in" => null, //档案进价
                    "prc_in_actual" => null, //实际进价
                    "unit" => null, //单位
                    "in_code" => null, //录入码
                    "barcode" => null, //条码
                    "remark" => null //单行备注
                ]
            ];
            $cr = $query["table_detail"]; //订单明细数据
            for ($i = 0; $i < count($cr); $i++) {
                $insert_data[$i]["order_dbid"] = $data_now["dbid"]; //对应订单数据编号
                $insert_data[$i]["goods_dbid"] = $cr[$i]["goods_dbid"]; //商品数据编号
                $insert_data[$i]["number"] = $cr[$i]["number"]; //数量
                $insert_data[$i]["prc_in"] = $cr[$i]["prc_in"]; //档案进价
                $insert_data[$i]["prc_in_actual"] = $cr[$i]["prc_in_actual"]; //实际进价
                $insert_data[$i]["unit"] = $cr[$i]["unit"]; //单位
                $insert_data[$i]["in_code"] = $cr[$i]["in_code"]; //录入码
                $insert_data[$i]["barcode"] = $cr[$i]["barcode"]; //条码
                $insert_data[$i]["remark"] = $cr[$i]["remark"]; //单行备注
            }
            // 写入订单头成功-得到订单号后-写入订单明细
            //分批写入每次最多100条数据
            $sql_insert_table_detail = Db::name('ai_t_goods_stock_order_detail')
                ->strict(false)
                ->limit(100)
                ->insertAll($insert_data);

            if ($sql_insert_table_detail) {
                $code = 200;
                $msg = "单据保存-成功";
                // 更新订单头字段-明细写入长度
                $mysql_data_now = mysql::where('dbid', '=', $data_now["dbid"])->find();
                $mysql_data_now->detail_length_insert = $sql_insert_table_detail; //明细写入长度
                $mysql_data_now->save();
                if ($sql_insert_table_detail != count($query["table_detail"])) {
                    $code = 203;
                    $msg = "订单明细写入-成功-但条目不相等";
                }
            } else {
                $code = 202;
                $msg = "订单明细写入-失败";
            }
        } else {
            $code = 201;
            $msg = "订单表头写入-失败";
            $data_now = [];
        }



        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $data_now,
            'sql_insert_table_detail' => $sql_insert_table_detail ? $sql_insert_table_detail : 0,
        ];
        return (json($apidb));
    }
    //修改
    public function up()
    {
        $query = request()->param(); //请求参数
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);

        // 查单头
        $sqldb = mysql::where('dbid', '=', $query["table_header"]["dbid"])->findOrEmpty();

        // 查询返回空
        if ($sqldb->isEmpty()) {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "查询不到相关单据", //状态信息
                'query' => $query, //请求参数
                'data' => [],
            ];
            return (json($apidb));
        };

        // 单据状态_A草稿B审核C作废
        if ($sqldb['state'] != 'A') {
            $apidb = [
                'code' => 205, //状态码
                'msg' => "此单据不能修改", //状态信息
                'query' => $query, //请求参数
                'data' => $sqldb,
            ];
            return (json($apidb));
        };


        $sqldb->time_up = $time_int; //修改时间
        $sqldb->save();


        // 修改单头-成功
        if ($sqldb) {
            $code = 200;
            $msg = "查单头-成功";
            $sqldb = $sqldb->toArray();


            // <删除数据库的>
            // 再增加新商品
            // 查询单据明细数据
            $detail_db = Db::table('ai_t_goods_stock_order_detail')->where('order_dbid', $sqldb["dbid"])->select();


            // 删除数据库的
            if ($detail_db) {
                for ($i = 0; $i < count($detail_db); $i++) {
                    $deleteok =   Db::table('ai_t_goods_stock_order_detail')->where('order_dbid', '=', $sqldb["dbid"])->delete();
                }
            }



            $cr = $query["table_detail"]; //订单明细数据
            for ($i = 0; $i < count($cr); $i++) {
                $insert_data[$i]["order_dbid"] = $sqldb["dbid"]; //对应订单数据编号
                $insert_data[$i]["goods_dbid"] = $cr[$i]["goods_dbid"]; //商品数据编号
                $insert_data[$i]["number"] = $cr[$i]["number"]; //数量
                $insert_data[$i]["prc_in"] = $cr[$i]["prc_in"]; //档案进价
                $insert_data[$i]["prc_in_actual"] = $cr[$i]["prc_in_actual"]; //实际进价
                $insert_data[$i]["unit"] = $cr[$i]["unit"]; //单位
                $insert_data[$i]["in_code"] = $cr[$i]["in_code"]; //录入码
                $insert_data[$i]["barcode"] = $cr[$i]["barcode"]; //条码
                $insert_data[$i]["remark"] = $cr[$i]["remark"]; //单行备注
            }
            // 写入订单头成功-得到订单号后-写入订单明细
            //分批写入每次最多100条数据
            $sql_insert_table_detail = Db::name('ai_t_goods_stock_order_detail')
                ->strict(false)
                ->limit(100)
                ->insertAll($insert_data);

            if ($sql_insert_table_detail) {
                $code = 200;
                $msg = "单据保存-成功";
                // 更新订单头字段-明细写入长度
                $mysql_data_now = mysql::where('dbid', '=', $sqldb["dbid"])->find();
                $mysql_data_now->detail_length_insert = $sql_insert_table_detail; //明细写入长度
                $mysql_data_now->time_up = $time_int; //修改时间

                $mysql_data_now->save();
                if ($sql_insert_table_detail != count($query["table_detail"])) {
                    $code = 203;
                    $msg = "订单明细写入-成功-但条目不相等";
                }
                $data_now = $sqldb;
            } else {
                $code = 202;
                $msg = "订单明细写入-失败";
            }
        } else {
            $code = 201;
            $msg = "订单表头修改-失败";
            $data_now = [];
        }



        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $data_now,
        ];
        return (json($apidb));
    }
    // 查询一条单据
    public function id()
    {
        $query = request()->param(); //请求参数
        // 查单头
        if (isset($query["dbid"]) && $query["dbid"] != "") {
            $sqldb = mysql::where('dbid', '=', $query["dbid"])->find(); //精准查询
        } else {
            $sqldb = mysql::order("id", "desc")->find(); //空查返回最新一条数据
        };




        // 单据头部-成功-查明细
        if ($sqldb) {
            //设置需要输出的属性
            $sqldb = $sqldb->visible([
                //     'id', //主键
            ]);
            // 设置需要隐藏的输出属性
            $sqldb = $sqldb->hidden([
                //     'id', //主键
            ]);
            // 设置需要附加的输出属性
            $sqldb = $sqldb->append([
                'table_detail', //附加字段-单据明细
            ]);
            // 设置数据字段获取器
            $sqldb = $sqldb->withAttr('db_state', function ($value, $data) {
                $res = ["A" => '删除', "B" => '停用', "C" => '只销'];
                return  ["val" => $value, "mp" => $res[$value], "txt" => "商品状态"];
            });
            $sqldb = $sqldb->withAttr('unit_pack', function ($value, $data) {
                $res = ["A" => '是', "B" => '否'];
                return  ["val" => $value, "mp" => $res[$value], "txt" => "是否大单位"];
            });
            $sqldb = $sqldb->withAttr('time_new', function ($value, $data) {
                return  ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "创建时间"];
            });
            $sqldb = $sqldb->withAttr('time_up', function ($value, $data) {
                return  ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "修改时间"];
            });

            // 查单头成功查单据明细

            $sql_table_detail =  Db::table('ai_t_goods_stock_order_detail')
                ->where('order_dbid', '=',  $sqldb['dbid'])
                ->order("id", "desc")
                ->withAttr('unit_pack', function ($value, $data) {
                    // 设置数据字段获取器
                    $res = ["A" => '是', "B" => '否'];
                    return  ["val" => $value, "mp" => $res[$value], "txt" => "是否大单位"];
                })
                ->select()
                ->toArray();
            if ($sql_table_detail) {
                $code = 200;
                $msg = "查询明细-成功";
                $sqldb["table_detail"] = $sql_table_detail;
            } else {
                $code = 200;
                $msg = "查询明细-成功-0条";
                $sqldb["table_detail"] = [];
            }

            $sqldb->detail_length_insert = count($sql_table_detail); //明细写入长度
            $sqldb->save();
        } else {
            $code = 201;
            $msg = "单据不存在";
            $sqldb["table_detail"] = [];
        }

        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb,
        ];
        return (json($apidb));
    }
    // 列表
    public function List()
    {
        $query = request()->param(); //请求参数
        $limit = request()->param('limit', 10, 'trim'); //每页行数
        $current = request()->param('current', 1, 'trim'); //页码

        if ($query["additional"]["use"] == 1) {
            // additional.use启用额外查询方法-0否-1是。
            $SearchField = $query["additional"]["SearchField"]; //搜索字段
            $SearchOperator = $query["additional"]["SearchOperator"]; //搜索查询表达式
            $SearchaAtistop = $query["additional"]["SearchaAtistop"]; //搜索关键词SearchaAtistop:"[4,28,29,30,31,32,33,34]"

        } else {
            $SearchField = request()->param('SearchField', 'id', 'trim'); //搜索字段
            $SearchOperator = request()->param('SearchOperator', 'LIKE', 'trim'); //搜索查询表达式
            $SearchaAtistop = strval(request()->param('SearchaAtistop', "", 'trim')); //搜索关键词

        }
        $SearchaSort = request()->param('SearchaSort', 'DESC', 'trim'); //搜索排序方式ASE,DESC升降序
        $SearchaSortField = request()->param('SearchaSortField', 'id', 'trim'); //排序字段

        // 查询表达式
        if ($SearchOperator == 'LIKE') {
            $SearchaAtistop = '%' . $SearchaAtistop . '%';
        };
        if ($SearchField == 'time_new' || $SearchField == 'time_up') {
            if ($SearchOperator == '>' || $SearchOperator == '<') {
                $SearchaAtistop = strtotime(strval($SearchaAtistop));
                if ($SearchField == 'time_new') {
                    $SearchField = 'time_new';
                } else if ($SearchField == 'time_up') {
                    $SearchField = 'time_up';
                }
            }
        }
        $help = [
            "db" => [
                "total" => "数据总行数",
                "per_page" => "每页数量",
                "current_page" => "当前页码",
                "last_page" => "最后一页/总页数",
                "data" => "数据集",
                "SearchaAtistop" => $SearchaAtistop
            ]
        ];
        $sqldb = mysql::where([
            [$SearchField, $SearchOperator, $SearchaAtistop],
            // ["cls_id", "IN", [1, 150, 129, 128, 123, 124, 154, 120, 121, 122]],
            // ["state", "=", "B"], //单据状态_A草稿B审核C作废

        ])
            ->order($SearchaSortField, $SearchaSort)
            ->paginate([ //[文档]https://www.kancloud.cn/manual/thinkphp6_0/1037638
                'list_rows'  => $limit, // 每页数量
                'page'  => $current, // 当前页
                // 'query' => $query,//url额外参数
            ]);



        // 设置数据字段获取器
        //   单据类型_A1采购入库B1采购退货C1赠品入库D1报损出库
        $sqldb = $sqldb->withAttr('type', function ($value, $data) {
            $res = ["A1" => '采购入库', "B1" => '采购退货', "C1" => '赠品入库', "D1" => '报损出库'];
            return  ["val" => $value, "mp" => $res[$value], "txt" => "单据类型"];
        });
        // 单据状态_A草稿B审核C作废
        $sqldb = $sqldb->withAttr('state', function ($value, $data) {
            $res = ["A" => '草稿', "B" => '审核', "C" => '作废'];
            return  ["val" => $value, "mp" => $res[$value], "txt" => "单据状态"];
        });
        $sqldb = $sqldb->withAttr('time_new', function ($value, $data) {
            return  ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "创建时间"];
        });
        $sqldb = $sqldb->withAttr('time_up', function ($value, $data) {
            return  ["val" => $value, "mp" => date('Y-m-d H:i:s', $value), "txt" => "修改时间"];
        });


        $sqldb2 = $sqldb->toArray();


        //  当前页起始行
        if ($current > 1) {
            $index2 = $limit * $current - $limit + 1;
        } else {
            $index2 = 1;
        }
        // echo "当前总下标：" . $index2;
        for ($x = 0; $x < count($sqldb); $x++) {
            $sqldb2["data"][$x]['index1'] = $x + 1;
            $sqldb2["data"][$x]['index2'] = $index2;
            $index2++;

            $reset = null;
            // $reset = Db::table('ai_t_goods_cls')->where('id', $sqldb2["data"][$x]['cls_id'])->find();

            // $sqldb2["data"][$x]['cls_name'] = !empty($reset["name"]) ? $reset["name"] : "!断链分类" . $sqldb2["data"][$x]['cls_id'];



        }
        $apidb = [
            'api' => ["name" => "采购单据列表", "help" => $help], //API信息
            'code' => 200, //状态码
            'msg' => "查询成功！", //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb2,

        ];
        return (json($apidb));
    }
    // 审核-写库存
    public function Finish()
    {
        $query = request()->param(); //请求参数
        $time_int = time();
        $time = date('Y-m-d H:i:s', $time_int);

        // 查单头
        $sqldb = mysql::where([
            ['dbid', '=', $query["table_header"]["dbid"]],
            // ['state', '=', 'A'], //单据状态_A草稿B审核C作废
        ])->findOrEmpty();

        // 查询返回空
        if ($sqldb->isEmpty()) {
            $apidb = [
                'code' => 201, //状态码
                'msg' => "查询不到相关单据", //状态信息
                'query' => $query, //请求参数
                'data' => [],
            ];
            return (json($apidb));
        } else {
            // 单据状态_A草稿B审核C作废
            if ($sqldb['state'] != 'A') {
                $apidb = [
                    'code' => 205, //状态码
                    'msg' => "此单据不能审核", //状态信息
                    'query' => $query, //请求参数
                    'data' => $sqldb,
                ];
                return (json($apidb));
            };

            // 获取-单据明细
            $sql_detail =   Db::table('ai_t_goods_stock_order_detail')->where('order_dbid', '=', $sqldb['dbid'])->select();
            if ($sql_detail) {
                // 遍历-单据明细
                foreach ($sql_detail as $item) {
                    // dump($item['goods_dbid']); //商品数据编号
                    // dump($item['number']); //数量
                    $detail_id = Db::table('ai_t_goods_stock')->where('goods_dbid', '=', $item['goods_dbid'])->find(); //查-库存信息
                    if ($detail_id) {
                        // 库存信息-存在-累加
                        $number = $detail_id["number"] + $item['number'];
                        //更新库存
                        $update =  Db::name('ai_t_goods_stock')->where('goods_dbid', '=', $item['goods_dbid'])->update(['number' => $number]);
                        if ($update) {
                            // 更新库存-成功
                            $code = 200; //状态码
                            $msg = "审核成功"; //状态信息
                            $sqldb->time_up = $time_int; //修改时间
                            $sqldb->state = "B"; //单据状态_A草稿B审核C作废
                            $sqldb->save();
                        } else {
                            $code = 201; //状态码
                            $msg = "审核-失败"; //状态信息
                        }
                    } else {
                        // 库存信息-不存在-新增
                        $data = ['goods_dbid' => $item['goods_dbid'], 'number' =>  $item['number']];
                        $insert_id = Db::name('ai_t_goods_stock')->insert($data);
                        if ($insert_id) {
                            // 写入库存信息-成功
                            // dump($insert_id);
                            $code = 200; //状态码
                            $msg = "审核成功"; //状态信息
                            $sqldb->time_up = $time_int; //修改时间
                            $sqldb->state = "B"; //单据状态_A草稿B审核C作废
                            $sqldb->save();
                        } else {
                            $code = 202; //状态码
                            $msg = "审核-失败"; //状态信息
                        }
                    }
                }
            } else {
                $code = 203; //状态码
                $msg = "审核失败-单据明细没数据"; //状态信息
            }
        }



        $apidb = [
            'code' => $code, //状态码
            'msg' => $msg, //状态信息
            'query' => $query, //请求参数
            'data' => $sqldb,
        ];
        return (json($apidb));
    }
}
